package EP1.algoritmos.algoritmo2;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;

import EP1.algoritmos.Primes;

public class Algoritmo2 implements Runnable {

    public static BigInteger sum;
    
    private int thread;
    private int n_threads;
    private int n;
    private ArrayList<Integer> primeList;

    public Algoritmo2(ArrayList<Integer> primeList, int n,
	    int n_threads, int thread) {

	this.n = n;
	this.n_threads = n_threads;
	this.thread = thread;
	this.primeList = primeList;
    }

    public static BigInteger calculaSoma(int cores, int n) {
	int max_size = n + 1;
	ArrayList<Thread> thread = new ArrayList<Thread>();
	ArrayList<Integer> primeList = new ArrayList<Integer>();

	sum = BigInteger.ZERO;
	
	if (cores == 1) {
	    Primes primes = new Primes(primeList, 1);

	    primes.makePrimesTo(max_size);

	    for (int i = 1; i < n; i++) {
		long ei = primes.getPrimeList().get(i - 1)
			+ primes.getPrimeList().get(i);
		long ej = primes.getPrimeList().get(i + 1)
			+ primes.getPrimeList().get(i);
		BigDecimal dec1 = new BigDecimal(ei);
		BigDecimal dec2 = new BigDecimal(ej);
		dec1 = dec1.multiply(dec2);
		sum = sum.add(dec1.toBigInteger());
	    }
	    return sum;
	    
	} else {

	    Primes p = new Primes(primeList, cores);
	    p.makePrimesTo(n + 1);

	    int n_threads = cores;
	    for (int i = 1; i <= n_threads; i++) {
		thread.add(new Thread(new Algoritmo2(primeList, n,
			n_threads, i)));
	    }

	    for (Thread t : thread) {
		t.start();
	    }

	    for (Thread t : thread) {
		try {
		    t.join();
		} catch (InterruptedException e) {
		}
	    }
	    return sum;
	}
    }

    @Override
    public void run() {
	BigInteger parcial = BigInteger.ZERO;

	for (int i = this.thread; i < n; i += n_threads) {
	    Long ei = new Long(primeList.get(i - 1) + primeList.get(i));
	    Long ej = new Long(primeList.get(i + 1) + primeList.get(i));

	    BigInteger dec1 = new BigInteger(ei.toString());
	    BigInteger dec2 = new BigInteger(ej.toString());
	    parcial = parcial.add(dec1.multiply(dec2));
	}

	add(parcial);
    }
    
    public synchronized void add(BigInteger i){
	sum = sum.add(i);
    }
}
